/**
 * @(#)PersonMapper.java
 * 1.0, 2013-01-24
 */
package de.hdm.gruppenkalender.team04.db;

import de.hdm.gruppenkalender.team04.data.Person;
import de.hdm.gruppenkalender.team04.data.PersonImpl;
import java.rmi.RemoteException;
import java.util.Vector;
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;

// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
// #[regen=yes,id=DCE.745BD683-F0EF-6D62-7EB3-35E4ADFBCD47]
// </editor-fold>
/**
 * Mapper-Klasse, die {@link Person}-Objekte auf eine relationale
 * Datenbank abbildet.
 * <p>
 * Hierzu wird eine Reihe von Methoden zur Verfügung gestellt, mit deren Hilfe
 * z.B. Objekte gesucht, erzeugt, modifiziert und gelöscht werden können.
 * <p>
 * In Anlehung an:
 * de.hdm.thies.bankprojekt.db.AccountMapper
 *
 * @author Prof. Dr. Peter Thies
 *
 * @author Mathias Bendel (mb167)
 * @author Björn Fichnter (bf023)
 * @author Stefan Hettich (sh176)
 * @author René Kugel (rk044)
 * @author Mark Leonberger (ml072)
 * @author Marta Przybylski (mp070)
 *
 * @version 1.0, 2013-01-24
 *
 */
public class PersonMapper {

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.438D785B-6F9F-B98E-4D3A-09D6632FFACE]
    // </editor-fold>
    /**
     * Die Klasse PersonMapper wird nur einmal instantiiert. Man spricht hierbei
     * von einem sogenannten <b>Singleton</b>.
     * <p>
     * Diese Variable ist durch den Bezeichner <code>static</code> nur einmal für
     * sämtliche eventuellen Instanzen dieser Klasse vorhanden. Sie speichert die
     * einzige Instanz dieser Klasse.
     *
     * @see #personMapper() 
     */
    private static PersonMapper personMapper;

    /**
     * Geschützter Konstruktor - verhindert die Möglichkeit, mit new neue
     * Instanzen dieser Klasse zu erzeugen.
     */
    protected PersonMapper() {
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.F622CB6A-EB06-551A-6182-8E56E7775392]
    // </editor-fold>
    /**
     * Diese statische Methode kann aufgrufen werden durch
     * <code>PersonMapper.personMapper()</code>. Sie stellt die
     * Singleton-Eigenschaft sicher, indem Sie dafür sorgt, daß nur eine einzige
     * Instanz von <code>KalendereintragMapper</code> existiert.
     *
     * @return {@link PersonMapper}-Objekt.
     * @see #personMapper
     */
    public static PersonMapper personMapper() {
        if (personMapper == null) {
            personMapper = new PersonMapper();
        }

        return personMapper;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.3B7000F3-C265-B711-51F3-8F7C92A1AAA9]
    // </editor-fold>
    /**
     * Gibt ein Objekt mit übergegebener Id zurück.
     *
     * @param   id
     * @return  Person  {@link Person}-Objekt, oder null wenn keines gefunden wurde.
     */
    public Person findeViaSchluessel(int id) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            ResultSet rs = stmt.executeQuery(
                    "SELECT personId, nachname, vorname, raum, telefon, email FROM person " + "WHERE personId=" + id +
                    " ORDER BY nachname;");

            // Statement ausfüllen und als Query an die DB schicken
            if (rs.next()) {
                // Umwandlung in ein {@link Kalendereintrag}-Objekt.
                Person p = new PersonImpl();
                p.setPersonId(rs.getInt("personId"));
                p.setNachname(rs.getString("nachname"));
                p.setVorname(rs.getString("vorname"));
                p.setRaum(rs.getString("raum"));
                p.setTelefon(rs.getString("telefon"));
                p.setEmail(rs.getString("email"));

                con.close();

                System.out.println(PersonMapper.class.getName() +
                        " - findeViaSchluessel ausgeführt.");

                return p;
            }
        } catch (RemoteException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }

        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.2BA3642B-462F-C1CC-17C4-FDBBB1D1A7CF]
    // </editor-fold>
    /**
     * Auslesen aller {@link Person}-Objekte.
     *
     * @return  Vector<Person> Ein {@link Vector} mit {@link Person}-Objekten.
     */
    public Vector<Person> findeAlle() {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        Vector<Person> result = new Vector<Person>();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            ResultSet rs = stmt.executeQuery(
                    "SELECT personId, nachname, vorname, raum, telefon, email FROM person " +
                    " ORDER BY nachname");

            /**
             * Für jeden Eintrag im Suchergebnis wird nun
             * ein {@link Person}-Objekt erstellt.
             */
            while (rs.next()) {
                Person p = new PersonImpl();
                p.setPersonId(rs.getInt("personId"));
                p.setNachname(rs.getString("nachname"));
                p.setVorname(rs.getString("vorname"));
                p.setRaum(rs.getString("raum"));
                p.setTelefon(rs.getString("telefon"));
                p.setEmail(rs.getString("email"));
                result.addElement(p);
            }

            System.out.println(PersonMapper.class.getName() +
                    " - findeAlle ausgeführt.");

            con.close();

            return result;
        } catch (RemoteException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.6F3111EB-608A-E9C5-4615-30CF9A1439CC]
    // </editor-fold>
    /**
     * Einfügen eins {@link Person}-Objekts in die Datenbank.
     *
     * @param   p   das zu speichernde Objekt
     * @return  das gespeicherte Objekt.
     */
    public Person einfuegen(Person p) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Aktuell größte Id in der Datenbak wird abgerufen.
            ResultSet rs = stmt.executeQuery(
                    "SELECT MAX(personId) AS maxid " +
                    "FROM person ");

            if (rs.next()) {
                p.setPersonId(rs.getInt("maxid") + 1);
                stmt = con.createStatement();

                // Statement ausfüllen und als Query an die DB schicken
                stmt.executeUpdate(
                        "INSERT INTO person (personId, nachname, vorname, raum, telefon, email) " +
                        "VALUES ('" +
                        p.getPersonId() + "','" +
                        p.getNachname() + "','" +
                        p.getVorname() + "','" +
                        p.getRaum() + "','" +
                        p.getTelefon() + "','" +
                        p.getEmail() + "');");

                con.close();

                System.out.println(PersonMapper.class.getName() +
                        " - einfuegen ausgeführt.");

                return p;
            }
        } catch (RemoteException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.40D6C5F1-E4BD-DC1C-1197-6331A25D78E9]
    // </editor-fold>
    /**
     * Wiederholtes Schreiben eines Objekts in die Datenbank.
     *
     * @param   p   das Objekt, das in die DB geschrieben werden soll
     * @return  das als Parameter übergebene Objekt
     */
    public Person aktualisieren(Person p) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            stmt.executeUpdate("UPDATE person " +
                    "SET nachname='" + p.getNachname() + "', " +
                    "vorname='" + p.getVorname() + "', " +
                    "raum='" + p.getRaum() + "', " +
                    "telefon='" + p.getTelefon() + "', " +
                    "email='" + p.getEmail() + "' " +
                    "WHERE personId=" + p.getPersonId());

            con.close();

            System.out.println(PersonMapper.class.getName() +
                    " - aktualisieren ausgeführt.");

            return p;

        } catch (RemoteException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return null;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.EFB10541-C462-35C8-1A77-BA898D682733]
    // </editor-fold>
    /**
     * Löschen der Daten eines {@link Person}-Objekts aus der Datenbank.
     *
     * @param   id  des aus der DB zu löschenden "Objekts".
     */
    public void loeschen(int id) {
        // DB-Verbindung holen
        Connection con = DBVerbindung.connection();

        try {
            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            // Statement ausfüllen und als Query an die DB schicken
            stmt.executeUpdate("DELETE FROM person " +
                    "WHERE personId=" + id);

            con.close();

            System.out.println(PersonMapper.class.getName() +
                    " - loeschen ausgeführt.");

        } catch (SQLException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
    }
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.5350AC72-1846-397B-845C-41316DE8FBEA]
    // </editor-fold>

    /**
     * Löschen der Daten eines {@link Person}-Objekts aus der Datenbank.
     *
     * @param   p  das aus der DB zu löschende "Objekt".
     */
    public void loeschen(Person p) {
        try {
            this.loeschen(p.getPersonId());
        } catch (RemoteException ex) {
            Logger.getLogger(PersonMapper.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
    }
}
